module alu_bench;

	reg [15:0] A,B;
	reg [2:0] Op;
	reg Cin,invA,invB,sign;
	wire [15:0] Out;
	wire Ofl,Zero;

	alu U0 (
		.A(A),.B(B),.Cin(Cin),
		.Op(Op),.invA(invA),.invB(invB),
		.sign(sign),.Out(Out),
		.Ofl(Ofl),.Z(Zero));
	integer k;
	initial
	begin
		Op = 3'b100;
		A = 16'HFFFF;
		B = 16'HFFFF;
		Cin = 1'b0;
		sign = 1'b1;
		invA = 1'b0;
		invB = 1'b0;
		#5	B = 16'H0000;
		#5	A = 16'H7FFF;
			B = 16'H7FFF;
		#5	A = 16'HFFFF;
			B = 16'H0001;
		#5	A = 16'H8000;
			B = 16'H8000;
		#5	sign = 1'b0;
		A = 16'HFFFF;
		B = 16'HFFFF;
		#5	B = 16'H0000;
		#5	A = 16'H7FFF;
			B = 16'H7FFF;
		
		#5	Op = 3'b101;
			A = 16'H00FF;
			B = 16'H0F0F;
		#5	Op = 3'b110;
		#5	Op = 3'b111;
		#5	A = 16'HFF00;
			Op[2] = 1'b0;
		for (k=0; k<=63; k=k+1)
			#5	{Op[1:0],B[3:0]}=k;
		#10	$finish;
	end
	//	Output monitors
	always@(Op,A,B)
	begin
		#1;
		if (Op==3'b100)
			$display("ADD: Op=%b A=%H B=%H Sign=%b Out=%H Ofl=%b Zero=%b",
			Op,A,B,sign,Out,Ofl,Zero);
		if (Op==3'b101)
			$display("OR: A=%b B=%b Out=%b",A,B,Out);
		if (Op==3'b110)
			$display("XOR: A=%b B=%b Out=%b",A,B,Out);
		if (Op==3'b111)
			$display("AND: A=%b B=%b Out=%b",A,B,Out);
		if (Op==3'b000)
			$display("rotate left: A=%b Cnt=%H Out=%b",A,B[3:0],Out);
		if (Op==3'b001)
			$display("shift left: A=%b Cnt=%H Out=%b",A,B[3:0],Out);
		if (Op==3'b010)
			$display("shift right arithmetic: A=%b Cnt=%H Out=%b",A,B[3:0],Out);
		if (Op==3'b011)
			$display("shift right logic: A=%b Cnt=%H Out=%b",A,B[3:0],Out);
	end
endmodule
